home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #2
/
Amiga Plus CD - 1995 - No. 2.iso
/
startrek
/
trek73
/
src
/
subs.c
< prev
Wrap
C/C++ Source or Header
|
1995-04-11
|
8KB
|
415 lines
/*
* TREK73: subs.c
*
* Miscellaneous Subroutines
*
* ship_name, newitem, delitem, rangefind, bearing, phaser_hit,
* torpedo_hit, damage, antimatter_hit, recitfy
*/
#include "defines.h"
#include "structs.h"
#include <math.h>
#include <ctype.h>
extern struct ship *shiplist[];
extern char science[];
struct ship *ship_name(name, start)
char *name;
int start;
{
extern int shipnum;
register int i;
register int j;
register int len;
if (islower(*name)) {
*name = toupper(*name);
}
j = shipnum;
len = strlen(name);
for (i=start; i<=j; i++) {
if (shiplist[i]->name[0] == NULL)
continue;
if (strncmp(name, shiplist[i]->name, len) == 0)
return shiplist[i];
}
printf("%s: I am unable to find the %s\n", science, name);
return NULL;
}
struct list *newitem(item)
int item;
{
extern struct list head;
extern struct list *tail;
register struct list *new;
register struct list *newtail;
/*
* if there's no "tail" node, make one (only happens at init)
*/
if (tail == NULL) {
new = MKNODE(struct list, *, 1);
new->back = &head;
new->fwd = NULL;
new->data.tp = NULL;
head.fwd = new;
tail = new;
}
new = tail;
/*
* now make the new tail node
*/
newtail = MKNODE(struct list, *, 1);
newtail->back = new;
newtail->fwd = NULL;
newtail->data.tp = NULL;
newtail->type = 0;
tail = newtail;
/*
* link the old tail node to the new one
*/
new->type = item;
new->fwd = newtail;
return new;
}
int delitem(item)
struct list *item;
{
extern struct list *tail;
extern struct list head;
register struct list *bp;
register struct list *fp;
bp = item->back;
fp = item->fwd;
if (item->data.tp != NULL)
free((char *) item->data.tp);
/*
* re-arrange pointers on both the next and the previous
* nodes; if no forward pointer, we were the tail so make
* the bp the new tail node.
*/
if (fp != NULL) {
bp->fwd = fp;
fp->back = bp;
} else {
tail = bp;
bp->fwd = NULL;
}
free((char *) item);
}
int rangefind(x1, x2, y1, y2)
int x1;
int x2;
int y1;
int y2;
{
extern double sqrt();
extern double atan();
register int i;
register int x, y;
double d1, d2;
x = x2 - x1;
y = y2 - y1;
/*
* Both x and y must be cast as double else overflow
* may occur.
*/
d1 = (double) x * (double) x + (double) y * (double) y;
d2 = sqrt(d1);
i = d2;
return i;
}
/*
* This routine finds the bearing of (x2,y2) from (x1,y1)
*/
int bearing(x1, x2, y1, y2)
int x1;
int x2;
int y1;
int y2;
{
extern double atan();
float x;
float y;
register int bear;
double d1;
double d2;
x = x2 - x1;
y = y2 - y1;
if (x == 0.0)
bear = 90;
else {
d1 = y/x;
d2 = atan(d1) * 57.2958;
bear = d2;
}
if (x < 0.0 || y < 0.0) {
bear += 180;
if (x >= 0.0)
bear += 180;
}
return bear;
}
int phaser_hit(sp, x, y, bank, true_bear)
struct ship *sp;
int x;
int y;
struct phaser *bank;
int true_bear;
{
extern double sqrt();
register int hit;
int i;
int spread;
int bear;
double d1;
double d2;
hit = 0;
i = rangefind(sp->x, x, sp->y, y);
if (i < 1000) {
bear = bearing(sp->x, x, sp->y, y);
spread = rectify(true_bear - bear);
/*
* Check if a target is within the phaser spread
*/
if (spread > sp->p_spread && 360-spread > sp->p_spread)
return 0;
d1 = 1.0 - (float)i/1000.0;
d2 = (float)bank->load * sqrt(d1) * sp->p_percent / 100;
d2 = (float)bank->load * d2 * 45.0/(float)sp->p_spread * sp->p_percent / 100;
hit = d2/10.0;
}
return hit;
}
int torpedo_hit(fuel, x, y, tx, ty)
int fuel;
int x;
int y;
int tx;
int ty;
{
extern double sqrt();
register int hit;
int i;
double d1;
double d2;
float f1;
float f2;
hit = 0;
i = rangefind(x, tx, y, ty);
f1 = fuel * 5.0;
f2 = f1 * 10.0;
if (i < f2) {
d1 = 1.0 - (float)i/f2;
d2 = (float)f1 * sqrt(d1);
hit = d2;
}
return hit;
}
damage(hit, ep, s, dam)
int hit;
struct ship *ep;
int s;
struct damage *dam;
{
register int i;
register int j;
register int k;
float f1;
float f2;
struct ship *fed;
fed = shiplist[0];
printf("hit %d on %s's shield %d\n", hit, ep->name, s);
s--;
/*
* Note that if the shield is at 100% efficiency, no
* damage at all will be taken
*/
f1 = hit * (1.0 - ep->shields[s].eff * ep->shields[s].drain);
if (f1 < 0)
return 0;
ep->eff += f1/dam->eff;
ep->pods -= f1/dam->fuel;
ep->energy -= f1/dam->fuel;
ep->regen -= f1/dam->regen;
if (ep->regen < 0.0)
ep->regen = 0.0;
if (ep->pods < 0.0)
ep->pods = 0.0;
if (ep->energy < 0.0)
ep->energy = 0.0;
if (ep->pods < ep->energy)
ep->energy = ep->pods;
f2 = dam->shield * 100;
if (s == 0)
f2 *= 1.5;
ep->shields[s].eff -= max(hit/f2, 0);
if (ep->shields[s].eff < 0.0)
ep->shields[s].eff = 0.0;
j = f1 * dam->crew;
if (j > 0)
ep->crew -= max(randm(j), 0);
if (ep->crew < 0)
ep->crew = 0;
j = f1/dam->weapon;
for(i=0; i<j; i++) {
k = randm(10);
if (k <= 4) {
k--;
if (ep->phasers[k].status & P_DAMAGED)
continue;
ep->phasers[k].status |= P_DAMAGED;
/*
* Reroute the energy
* back to the engines
*/
ep->energy = min(ep->pods,
ep->energy + ep->phasers[k].load);
ep->phasers[k].load = 0;
ep->phasers[k].drain = 0;
k++;
if (ep == fed)
printf(" phaser %d damaged.\n", k);
} else {
k -= 5;
if (ep->tubes[k].status & T_DAMAGED)
continue;
/*
* If tubes are damaged, reroute the pods
* back to the engines
*/
ep->pods += ep->tubes[k].load;
ep->energy += ep->tubes[k].load;
ep->tubes[k].load = 0;
ep->tubes[k].status |= T_DAMAGED;
k++;
if (ep == fed)
printf(" tube %d damaged\n", k);
}
}
for (i=0; i<4; i++) {
if (ep->status & 1<<i)
continue;
if (randm(dam->stats[i].roll) < f1) {
ep->status |= 1<<i;
if (ep == fed)
printf(" %s\n", dam->stats[i].mesg);
}
}
#ifdef HISTORICAL
/*
* Historically, if more than 43 points of damage were done
* to the ship, it would destroy itself. This led to much
* abuse of probes and thus has been enclosed inside of
* an #ifdef
*/
if (f1 > 43)
ep->delay = 1;
#endif
return 0;
}
antimatter_hit(ptr, x, y, fuel)
char *ptr;
int x;
int y;
int fuel;
{
extern struct list head;
extern struct list *tail;
extern struct damage a_damage;
register struct list *lp;
register int hit;
int tarx, tary;
int s;
int bear;
struct torpedo *tp;
struct ship *sp;
for (lp = &head; lp != tail; lp = lp->fwd) {
if (lp->type == 0)
continue;
sp = NULL;
tp = NULL;
if (lp->type == I_SHIP) {
sp = lp->data.sp;
tarx = sp->x;
tary = sp->y;
} else {
tp = lp->data.tp;
tarx = tp->x;
tary = tp->y;
}
if (sp == (struct ship *) ptr || tp == (struct torpedo *) ptr)
continue;
hit = torpedo_hit(fuel, x, y, tarx, tary);
if (hit <= 0)
continue;
if (sp) {
/*
* Determine which shield is hit
*/
bear = rectify(bearing(tarx, x, tary, y) - sp->course);
if (bear < 45 || bear > 315)
s = 1;
else if (bear < 135)
s = 2;
else if (bear < 225)
s = 3;
else
s = 4;
damage(hit, sp, s, &a_damage);
} else {
if (tp->timedelay <= 2)
continue;
tp->timedelay = 2;
switch (lp->type) {
case I_TORPEDO:
printf("hit on torpedo %d\n",
tp->id);
break;
case I_PROBE:
printf("hit on probe %d\n",
tp->id);
break;
case I_ENG:
printf("hit on %s engineering\n",
tp->from->name);
break;
}
}
}
}
int rectify(x)
int x;
{
register int ret;
ret = x;
if (ret < 0)
ret += 360;
else if (ret > 360)
ret -= 360;
return ret;
}